#include "pwm_out.h"

#define SET_PCA_PWM_DUTY(ch,v) M0P_PCA->CCAP##ch=v
#define PCAM_CARR_VALUE (3*2000)  //3Mhz -> 500hz

void pwm_out_init(void)
{
	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, 1);
	Sysctrl_SetPeripheralGate(SysctrlPeripheralPca, 1);
	
	M0P_PCA->CCON_f.CR = 0;	
	M0P_PCA->CMOD_f.CPS = 2;  //24/8=3M	
	M0P_PCA->CNT_f.CNT = 0;	
	M0P_PCA->EPWM_f.EPWM = 1;
	
	//PA4-PCA-CH4, PB00-PCA-CH2
	M0P_PCA->CCAPM2_f.ECOM = 1;
	M0P_PCA->CCAPM2_f.PWM = 1;
	//M0P_PCA->CCAPM2_f.MAT = 1;
	M0P_PCA->CCAPM2_f.TOG = 1;
	
	M0P_PCA->CCAPM4_f.ECOM = 1;
	M0P_PCA->CCAPM4_f.PWM = 1;
	//M0P_PCA->CCAPM4_f.MAT = 1;
	M0P_PCA->CCAPM4_f.TOG = 1;
	
	M0P_PCA->CARR_f.CARR = PCAM_CARR_VALUE; //500hz
	M0P_PCA->CCAP2_f.CCAP2 = 0;
	M0P_PCA->CCAP4_f.CCAP4 = 0;
	
	pwm_out_close();
}

void pwm_out_start(void)
{
	M0P_PCA->CCON_f.CR = 1;
}

//1 : CHB
//0 : CHA
void pwm_out_close(void)
{
	SET_PCA_PWM_DUTY(2, PCAM_CARR_VALUE+1);
	SET_PCA_PWM_DUTY(4, PCAM_CARR_VALUE+1);
}

void pwm_out_level(uint8_t ch, uint8_t le)
{
	uint16_t v = le?0:(PCAM_CARR_VALUE+1);
	if(ch)
	{
		SET_PCA_PWM_DUTY(2, v);
	}
	else
	{
		SET_PCA_PWM_DUTY(4, v);
	}
}

void pwm_out(uint8_t ch, float duty)
{
	uint32_t cnt = 0;
	
	duty += 10.0f;
	if(duty<=11.0f)
	{
		pwm_out_close();
		return;
	}
	else
	{
		duty = 100-(duty>=90.0f?90.0f:duty);
		cnt = (uint32_t)(PCAM_CARR_VALUE*(duty/100.0f));
	}

	if(cnt>0)
	{
		pwm_out_level(ch?0:1, 0);		
		if(ch)
			SET_PCA_PWM_DUTY(2, cnt);
		else
			SET_PCA_PWM_DUTY(4, cnt);
		M0P_PCA->CCON_f.CR = 1;
	}
	else
	{
		pwm_out_close();
	}
}
